home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp95
/
freyja.exe
/
lha
/
TERM.C
< prev
next >
Wrap
Text File
|
1992-04-13
|
14KB
|
866 lines
/* TERM.C -- Terminal Interface Routines
Written March 1991 by Craig A. Finseth
Copyright 1991 by Craig A. Finseth
*/
#include "freyja.h"
#if defined(UNIX)
#undef TRUE
#undef FALSE
#undef CR
#undef NL
#undef BS
#include <curses.h>
#if defined(UNIXV)
static int savemodes;
#else /* assume Berkeley sockets */
#endif
#endif
#if defined(UNIX)
#if defined(UNIXV)
#else /* assume Berkeley sockets */
#if defined(SUNOS3)
#define KERNEL 1 /* Sun repeats the declaration of struct tm */
#endif /* in this file, so we work around it */
#include <sys/time.h>
#if defined(SUNOS3)
#undef KERNEL
#endif
#include <sys/ioctl.h>
#define RFDSIZE 32 /* in bits */
static struct sgttyb savtty;
#endif
#endif
static int gotchar; /* buffered character */
static int offset; /* horizontal offset */
static int row; /* current row and column */
static int col;
static char printbuf[SMALLBUFFSIZE]; /* for TPrintChar */
static char outbuf[128]; /* output buffer */
static char *outptr;
static int width;
static int height;
#if defined(MSDOS)
#define NORMAL 7 /* normal video */
#define REVERSE 112 /* reverse video */
char t_attrib;
static char huge *scrnbase;
static char huge *scrnptr;
static int line_offsets[] = {
0, 160, 320, 480, 640, 800,
960, 1120, 1280, 1440, 1600,
1760, 1920, 2080, 2240, 2400,
2560, 2720, 2880, 3040, 3200,
3360, 3520, 3680, 3840, 4000 };
#endif
void T_RawChar(); /* char c */
void T_RawFlush(); /* void */
void T_RawStr(); /* char *str */
/* ------------------------------------------------------------ */
FLAG
TInit()
{
#if defined(UNIX)
#if !defined(UNIXV)
struct sgttyb tty;
#endif
#endif
gotchar = -1;
offset = 0;
row = 0;
col = 0;
outptr = outbuf;
width = 80;
height = 24;
#if defined(MSDOS)
if (c.g.screen_size == 'J') {
width = 40;
height = 16;
}
else {
if (c.g.screen_type == 'B' || c.g.screen_type == 'M')
height = 25;
}
#endif
switch (c.g.screen_type) {
case 'V':
#if defined(UNIX)
#if defined(UNIXV)
return(FALSE); /* not supported yet */
#else /* assume Berkeley sockets */
if (ioctl(0, TIOCGETP, (int)&tty) < 0) return(FALSE);
savtty = tty;
tty.sg_flags |= RAW;
tty.sg_flags &= ~ECHO;
if (ioctl(0, TIOCSETP, (int)&tty) < 0) return(FALSE);
#endif
/* set VT100 mode, origin relative, jump scroll */
if (c.g.screen_type == 'V') T_RawStr("\033<\033[?6h\033[?4l");
#endif
break;
#if defined(UNIX)
case 'T':
initscr();
noecho();
raw();
leaveok(stdscr, FALSE);
#if defined(UNIXV)
if ((savemodes = fcntl(STDIN, F_GETFL, 0)) < 0 ||
fcntl(STDIN, F_SETFL, savemodes | O_NDELAY) < 0) {
return(FALSE);
}
#endif
break;
#endif
#if defined(MSDOS)
case 'B':
t_attrib = NORMAL;
VidCurOn();
break;
case 'M':
t_attrib = NORMAL;
scrnbase = (char huge *)((long)VidInit() << 16);
scrnptr = scrnbase;
VidCurOn();
break;
#endif
}
TClrScreen();
return(TRUE);
}
/* ------------------------------------------------------------ */
/* Terminate special terminal handling. */
void
TFini()
{
TForce();
switch (c.g.screen_type) {
case 'V':
#if defined(UNIX)
#if defined(UNIXV)
#else /* assume Berkeley sockets */
ioctl(0, TIOCSETP, (int)&savtty);
#endif
#endif
break;
#if defined(UNIX)
case 'T':
#if defined(UNIXV)
fcntl(STDIN, F_SETFL, savemodes);
#endif
mvcur(0, COLS - 1, LINES - 1, 0);
clrtoeol();
refresh();
endwin();
break;
#endif
#if defined(MSDOS)
case 'B':
break;
case 'M':
VidFini();
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Adjust the column by the horizontal offset. */
void
TAdjCol()
{
col += offset;
}
/* ------------------------------------------------------------ */
/* Ring the terminal bell. */
void
TBell()
{
switch (c.g.screen_type) {
case 'V':
T_RawChar(BEL);
break;
#if defined(UNIX)
case 'T':
break;
#endif
#if defined(MSDOS)
case 'B':
case 'M':
VidBell();
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Clear to the end of the line. */
void
TCLEOL()
{
#if defined(MSDOS)
int cnt;
#endif
TForce();
switch (c.g.screen_type) {
case 'V':
T_RawStr("\033[K");
break;
#if defined(UNIX)
case 'T':
clrtoeol();
break;
#endif
#if defined(MSDOS)
case 'B':
VidClear(width - col);
break;
case 'M':
for (cnt = 0; cnt < width - col; cnt++) {
*scrnptr++ = SP;
*scrnptr++ = t_attrib;
}
scrnptr -= 2 * (width - col);
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Clear the entire screen and put the cursor at row,column 0,0. */
void
TClrScreen()
{
switch (c.g.screen_type) {
case 'V':
TSetPoint(0,0);
T_RawStr("\033[2J");
break;
#if defined(UNIX)
case 'T':
clear();
break;
#endif
#if defined(MSDOS)
case 'B':
case 'M':
col = 0;
for (row = 0; row < height; ++row) TCLEOL();
break;
#endif
}
TSetPoint(0, 0);
}
/* ------------------------------------------------------------ */
/* Force the cursor to be displayed at the current row,column. */
void
TForce()
{
#if defined(MSDOS)
int amt = col - offset;
if (amt < 0) amt = 0;
if (amt > width) amt = width;
#endif
switch (c.g.screen_type) {
case 'V':
T_RawFlush();
break;
#if defined(UNIX)
case 'T':
refresh();
break;
#endif
#if defined(MSDOS)
case 'B':
VidCursor(row, amt);
break;
case 'M':
scrnptr = scrnbase + line_offsets[row] + 2 * amt;
VidCursor(row, amt);
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Return the current cursor column. */
int
TGetCol()
{
return(col);
}
/* ------------------------------------------------------------ */
/* Wait for and return the next key. */
int
TGetKey()
{
int chr;
char cchr;
#if defined(MSDOS)
if (c.g.key_type == 'S') {
while (read(3, &cchr, 1) < 1) ;
return(cchr);
}
else {
chr = PSystem(0x7) & 0xFF;
if (chr == 0)
return(0x100 + (PSystem(0x7) & 0xFF));
else return(chr);
}
#endif
#if defined(UNIX)
if (gotchar != -1) {
chr = gotchar;
gotchar = -1;
return(chr);
}
switch (c.g.screen_type) {
case 'V':
#if defined(UNIXV)
return(0);
#else /* assume Berkeley sockets */
read(0, &cchr, sizeof(cchr));
return(cchr & 0xFF);
#endif
break;
case 'T':
#if defined(UNIXV)
read(0, &cchr, sizeof(cchr));
return(cchr & 0xFF);
#else /* assume Berkeley sockets */
return(getch() & 0xFF);
#endif
break;
}
#endif
}
/* ------------------------------------------------------------ */
/* Return the horizontal offset. */
int
TGetOffset()
{
return(offset);
}
/* ------------------------------------------------------------ */
/* Return the current cursor row. */
int
TGetRow()
{
return(row);
}
/* ------------------------------------------------------------ */
/* Return the width of character C as displayed by TPutChar, if C
started in the specified column. */
int
TGetWidth(chr, column)
char chr;
int column;
{
if (c.g.use_caret) {
if (chr >= SP && chr <= '~')
return(1);
else if (chr == TAB)
return(cbuf->c.tab_spacing -
(column % cbuf->c.tab_spacing));
else if (chr & 0x80)
return(1 + TGetWidth(chr & 0x7F, column + 1));
else return(1 + TGetWidth(chr ^ '@', column + 1));
}
else {
if (chr != TAB)
return(1);
else return(cbuf->c.tab_spacing -
(column % cbuf->c.tab_spacing));
}
}
/* ------------------------------------------------------------ */
/* Turn off highlighting. */
void
THiOff()
{
switch (c.g.screen_type) {
case 'V':
T_RawStr("\033[0m");
break;
#if defined(UNIX)
case 'T':
standend();
break;
#endif
#if defined(MSDOS)
case 'B':
case 'M':
t_attrib = NORMAL;
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Turn on highlighting. */
void
THiOn()
{
switch (c.g.screen_type) {
case 'V':
T_RawStr("\033[7m");
break;
#if defined(UNIX)
case 'T':
standout();
break;
#endif
#if defined(MSDOS)
case 'B':
case 'M':
t_attrib = REVERSE;
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Return 'Y', if a key is available, 'N' if not, or '?' if you can't
tell. */
char
TIsKey()
{
#if defined(MSDOS)
if (c.g.key_type == 'S')
return('?');
else return(PSystem(0xB) & 0xFF ? 'Y' : 'N');
#endif
#if defined(UNIX)
#if !defined(UNIXV)
struct timeval timeout;
fd_set rfd;
char chr;
#endif
if (gotchar != -1) return('Y');
switch (c.g.screen_type) {
case 'V':
#if defined(UNIXV)
return('?');
#else /* assume Berkeley sockets */
FD_ZERO(&rfd);
FD_SET(0, &rfd);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
if (select(RFDSIZE, &rfd, 0, 0, &timeout) == 1) {
read(0, &chr, sizeof(chr));
gotchar = chr & 0xFF;
return('Y');
}
else {
return('N');
}
#endif
break;
case 'T':
#if defined(UNIXV)
return('?');
#else /* assume Berkeley sockets */
FD_ZERO(&rfd);
FD_SET(0, &rfd);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
if (select(RFDSIZE, &rfd, 0, 0, &timeout) == 1) {
read(0, &chr, sizeof(chr));
gotchar = chr & 0xFF;
return('Y');
}
else {
return('N');
}
#endif
break;
}
#endif
}
/* ------------------------------------------------------------ */
/* Return the number of columns in the screen. */
int
TMaxCol()
{
#if defined(UNIX)
if (c.g.screen_type == 'T') return(COLS);
else
#endif
return(width);
}
/* ------------------------------------------------------------ */
/* Return the number of rows in the screen. */
int
TMaxRow()
{
#if defined(UNIX)
if (c.g.screen_type == 'T') return(LINES);
else
#endif
return(height);
}
/* ------------------------------------------------------------ */
/* Put a printed representation of the specified character in a
buffer. If BUF is not-NULL, use it (it should be at least
SMALLBUFFSIZE characters). Otherwise, use a static buffer. Return a
pointer to the start of the buffer. */
char *
TPrintChar(c, buf)
char c;
char *buf;
{
char *savebuf;
if (buf == NULL) buf = printbuf;
savebuf = buf;
c &= 0xff;
if (c & 0x80) {
*buf++ = '~';
c &= 0x7f;
}
if (c < SP || c == DEL) {
*buf++ = '^';
c ^= '@';
}
*buf++ = c;
*buf = NUL;
return(savebuf);
}
/* ------------------------------------------------------------ */
/* Put the character to the screen, expanding tabs and control
characters. */
void
TPutChar(chr)
char chr;
{
int cnt;
if (c.g.vis_gray) {
if (chr == SP) {
T_RawChar(VIS_SPACE_CHAR);
++col;
return;
}
else if (chr == VIS_NL_CHAR) {
T_RawChar(VIS_NL_CHAR);
++col;
return;
}
}
if (c.g.use_caret) {
if (chr >= SP && chr <= '~') {
T_RawChar(chr);
++col;
}
else if (chr == TAB) {
cnt = cbuf->c.tab_spacing - (col % cbuf->c.tab_spacing);
if (c.g.vis_gray) {
T_RawChar(VIS_TAB_CHAR);
++col;
cnt--;
}
for ( ; cnt > 0; cnt--, col++) T_RawChar(SP);
}
else if (chr & 0x80) {
TPutChar('~');
TPutChar(chr & 0x7f);
}
else {
TPutChar('^');
TPutChar(chr ^ '@');
}
}
else { /* just send it */
if (chr == TAB) {
cnt = cbuf->c.tab_spacing - (col % cbuf->c.tab_spacing);
if (c.g.vis_gray) {
T_RawChar(VIS_TAB_CHAR);
++col;
cnt--;
}
for ( ; cnt > 0; cnt--, col++) T_RawChar(SP);
}
else {
T_RawChar(chr);
++col;
}
}
}
/* ------------------------------------------------------------ */
/* Put the string to the screen, expanding each character as TPutChar.
*/
void
TPutStr(str)
char *str;
{
while (*str != NUL) TPutChar(*str++);
}
/* ------------------------------------------------------------ */
/* Set the horizontal offset. Set to 0 means no offset used. */
void
TSetOffset(o)
int o;
{
offset = o;
}
/* ------------------------------------------------------------ */
/* Set the cursor row and column. */
void
TSetPoint(xrow, xcol)
int xrow;
int xcol;
{
char buf[SMALLBUFFSIZE];
if (row == xrow && col == xcol) return;
row = xrow;
col = xcol;
switch (c.g.screen_type) {
case 'V':
xsprintf(buf, "\033[%d;%dH", row + 1, col + 1);
T_RawStr(buf);
break;
#if defined(UNIX)
case 'T':
move(row, col);
break;
#endif
#if defined(MSDOS)
case 'B':
case 'M':
TForce();
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Send the character to the screen, uninterpreted. */
void
T_RawChar(chr)
char chr;
{
int amt;
if (offset != 0 && col < offset) return;
switch (c.g.screen_type) {
case 'V':
*outptr++ = chr;
if (outptr >= &outbuf[sizeof(outbuf)]) T_RawFlush();
break;
#if defined(UNIX)
case 'T':
addch(chr);
break;
#endif
#if defined(MSDOS)
case 'B':
amt = col - offset;
if (amt < 0) amt = 0;
if (amt > width) amt = width;
VidCursor(row, amt);
VidChar(chr);
break;
case 'M':
*scrnptr++ = chr;
*scrnptr++ = t_attrib;
break;
#endif
}
}
/* ------------------------------------------------------------ */
/* Flush the output buffer. */
void
T_RawFlush()
{
if (outptr > outbuf) write(1, outbuf, outptr - outbuf);
outptr = outbuf;
}
/* ------------------------------------------------------------ */
/* Send the string to the screen, uninterpreted. */
void
T_RawStr(str)
char *str;
{
switch (c.g.screen_type) {
case 'V':
#if defined(MSDOS)
case 'B':
case 'M':
#endif
while (*str != NUL) T_RawChar(*str++);
break;
#if defined(UNIX)
case 'T':
addstr(str);
break;
#endif
}
}
/* end of TERM.C -- Terminal Interface Routines */